﻿using System;

using BodaNetCommunications.BeckhoffComs;
using BodaNetCommunications.Utilities.ComTypes;
using BodaNetCommunications.Utilities.Results;

namespace BodaNetCommunications.Utilities.DataLibs
{
    public class MigrationLib
    {
        private static string ByteMax = "255";

        private static string ByteMin = "0";

        private static string ShortMax = "32767";

        private static string ShortMin = "-32768";

        private static string UShortMax = "65535";

        private static string UShortMin = "0";

        private static string IntMax = "2147483647";

        private static string IntMin = "-2147483648";

        private static string UIntMax = "4294967295";

        private static string UIntMin = "0";

        private static string GetErrorMsg(DataType type)
        {
            string empty = string.Empty;
            switch (type)
            {
                case DataType.@byte:
                    {
                        empty = "设置范围：" + ByteMin + "-" + ByteMax;
                        break;
                    }
                case DataType.@short: { empty = "设置范围：" + ShortMin + "-" + ShortMax; break; }
                case DataType.@ushort: { empty = "设置范围：" + UShortMin + "-" + UShortMax; break; }
                case DataType.@int: { empty = "设置范围：" + IntMin + "-" + IntMax; break; }
                case DataType.@uint: { empty = "设置范围：" + UIntMin + "-" + UIntMax; break; }
                default: { empty = "设置范围超限"; break; }
            };

            return empty;
        }

        public static object GetMigrationValue(object value, string scale, string offset)
        {
            if (scale == "1" && offset == "0")
            {
                return value;
            }

            string name = value.GetType().Name;
            switch (name.ToLower())
            {
                case "byte":
                case "int16":
                case "uint16":
                case "int32":
                case "uint32":
                case "single":
                    return Convert.ToSingle((Convert.ToSingle(value) * Convert.ToSingle(scale) + Convert.ToSingle(offset)).ToString("N4"));

                case "int64":
                case "uint64":
                case "double":
                    return Convert.ToDouble((Convert.ToDouble(value) * Convert.ToDouble(scale) + Convert.ToDouble(offset)).ToString("N4"));

                default:
                    return value;
            }
        }

        public static BodaResult<string> SetMigrationValue(string set, DataType type, string scale, string offset)
        {
            BodaResult<string> bodaResult = new BodaResult<string>();
            if (scale == "1" && offset == "0")
            {
                try
                {
                    switch (type)
                    {
                        case DataType.@byte:
                            bodaResult.Content = Convert.ToByte(set).ToString();
                            break;

                        case DataType.@short:
                            bodaResult.Content = Convert.ToInt16(set).ToString();
                            break;

                        case DataType.@ushort:
                            bodaResult.Content = Convert.ToUInt16(set).ToString();
                            break;

                        case DataType.@int:
                            bodaResult.Content = Convert.ToInt32(set).ToString();
                            break;

                        case DataType.@uint:
                            bodaResult.Content = Convert.ToUInt32(set).ToString();
                            break;

                        case DataType.@long:
                            bodaResult.Content = Convert.ToInt64(set).ToString();
                            break;

                        case DataType.@ulong:
                            bodaResult.Content = Convert.ToUInt64(set).ToString();
                            break;

                        case DataType.@float:
                            bodaResult.Content = Convert.ToSingle(set).ToString();
                            break;

                        case DataType.@double:
                            bodaResult.Content = Convert.ToDouble(set).ToString();
                            break;

                        default:
                            bodaResult.Content = set;
                            break;
                    }

                    bodaResult.IsSuccess = true;
                    return bodaResult;
                }
                catch (Exception)
                {
                    bodaResult.IsSuccess = false;
                    bodaResult.Message = "转换出错，" + GetErrorMsg(type);
                    return bodaResult;
                }
            }

            try
            {
                switch (type)
                {
                    case DataType.@byte:
                        bodaResult.Content = Convert.ToByte((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@short:
                        bodaResult.Content = Convert.ToInt16((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@ushort:
                        bodaResult.Content = Convert.ToUInt16((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@int:
                        bodaResult.Content = Convert.ToInt32((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@uint:
                        bodaResult.Content = Convert.ToUInt32((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@long:
                        bodaResult.Content = Convert.ToInt64((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    case DataType.@ulong:
                        bodaResult.Content = Convert.ToUInt64((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    case DataType.@float:
                        bodaResult.Content = Convert.ToSingle((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case DataType.@double:
                        bodaResult.Content = Convert.ToDouble((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    default:
                        bodaResult.Content = set;
                        break;
                }

                bodaResult.IsSuccess = true;
                return bodaResult;
            }
            catch (Exception)
            {
                bodaResult.IsSuccess = false;
                bodaResult.Message = "转换出错，" + GetErrorMsg(type);
                return bodaResult;
            }
        }

        public static BodaResult<string> SetMigrationValue(string set, BeckhoffDataType type, string scale, string offset)
        {
            BodaResult<string> bodaResult = new BodaResult<string>();
            if (scale == "1" && offset == "0")
            {
                try
                {
                    switch (type)
                    {
                        case BeckhoffDataType.Byte:
                            bodaResult.Content = Convert.ToByte(set).ToString();
                            break;

                        case BeckhoffDataType.Short:
                            bodaResult.Content = Convert.ToInt16(set).ToString();
                            break;

                        case BeckhoffDataType.UShort:
                            bodaResult.Content = Convert.ToUInt16(set).ToString();
                            break;

                        case BeckhoffDataType.Int:
                            bodaResult.Content = Convert.ToInt32(set).ToString();
                            break;

                        case BeckhoffDataType.UInt:
                            bodaResult.Content = Convert.ToUInt32(set).ToString();
                            break;

                        case BeckhoffDataType.Long:
                            bodaResult.Content = Convert.ToInt64(set).ToString();
                            break;

                        case BeckhoffDataType.ULong:
                            bodaResult.Content = Convert.ToUInt64(set).ToString();
                            break;

                        case BeckhoffDataType.Float:
                            bodaResult.Content = Convert.ToSingle(set).ToString();
                            break;

                        case BeckhoffDataType.Double:
                            bodaResult.Content = Convert.ToDouble(set).ToString();
                            break;

                        default:
                            bodaResult.Content = set;
                            break;
                    }

                    bodaResult.IsSuccess = true;
                    return bodaResult;
                }
                catch (Exception)
                {
                    bodaResult.IsSuccess = false;
                    bodaResult.Message = "转换出错";
                    return bodaResult;
                }
            }

            try
            {
                switch (type)
                {
                    case BeckhoffDataType.Byte:
                        bodaResult.Content = Convert.ToByte((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.Short:
                        bodaResult.Content = Convert.ToInt16((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.UShort:
                        bodaResult.Content = Convert.ToUInt16((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.Int:
                        bodaResult.Content = Convert.ToInt32((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.UInt:
                        bodaResult.Content = Convert.ToUInt32((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.Long:
                        bodaResult.Content = Convert.ToInt64((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    case BeckhoffDataType.ULong:
                        bodaResult.Content = Convert.ToUInt64((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    case BeckhoffDataType.Float:
                        bodaResult.Content = Convert.ToSingle((Convert.ToSingle(set) - Convert.ToSingle(offset)) / Convert.ToSingle(scale)).ToString();
                        break;

                    case BeckhoffDataType.Double:
                        bodaResult.Content = Convert.ToDouble((Convert.ToDouble(set) - Convert.ToDouble(offset)) / Convert.ToDouble(scale)).ToString();
                        break;

                    default:
                        bodaResult.Content = set;
                        break;
                }

                bodaResult.IsSuccess = true;
                return bodaResult;
            }
            catch (Exception)
            {
                bodaResult.IsSuccess = false;
                bodaResult.Message = "转换出错";
                return bodaResult;
            }
        }
    }
}